package ch.unisi.inf.pfii.teamwhite.risk.graphic.menuFrame;

/**
 * 
 * @author Matteo Bellan: bellanm@lu.unisi.ch
 * @author Andrea Michelotti: micheloa@lu.unisi.ch
 * @author Ranganathan Ramasubramanian: ramasubr@lu.unisi.ch@lu.unisi.ch
 *
 */

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;

import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.KeyStroke;

import ch.unisi.inf.pfii.teamwhite.risk.core.Game;
import ch.unisi.inf.pfii.teamwhite.risk.graphic.gameFrame.GameFrame;
import ch.unisi.inf.pfii.teamwhite.risk.graphic.mapEditor.MapNameDialog;
import ch.unisi.inf.pfii.teamwhite.risk.graphic.menuFrame.dialogs.CreditsDialog;
import ch.unisi.inf.pfii.teamwhite.risk.graphic.menuFrame.dialogs.PlayerCreatorDialog;
import ch.unisi.inf.pfii.teamwhite.risk.sound.SoundEngine;

public final class MenuFrame extends JFrame{
	
	private Game game;

	private Container contentPane;
	private JPanel playerPanel;
	private JLabel imageLabel;
	private JButton start;
	private JButton create;
	
	private String map;
	public static final String PATH = "src/ch/unisi/inf/pfii/teamwhite/risk/graphic/maps/";
	private boolean soundEnabled;
	
	public MenuFrame(final Game game) {
		
		this.game = game;
		
		playerPanel = makePlayerPanel();
		
		map = "classic";
		soundEnabled = true;
		new SoundEngine("menu.wav", true, true);
		
		contentPane = getContentPane();
		contentPane.setLayout(new BorderLayout());
		makeMenuBar();
		contentPane.add(makeNorth(), BorderLayout.NORTH);
		contentPane.add(makeSouth(), BorderLayout.SOUTH);
		
		setTitle("Main Menu");
		setDefaultCloseOperation(HIDE_ON_CLOSE);
		setSize(800, 600);
		setResizable(false);
		setLocationRelativeTo(null);
		setVisible(true);
		pack();
	}
	
	private final void start() {
		setVisible(false);
		new GameFrame(game, map, soundEnabled);
	}
	
//	This method creates the menu bar where you can set if the sounds are enabled or not, view credits and quit
	private final void makeMenuBar() {
		final int SHORTCUT_MASK = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
		
		final JMenuBar menuBar = new JMenuBar();
		final JMenu fileMenu = new JMenu("File");
		menuBar.add(fileMenu);
		final JMenuItem start = new JMenuItem("Sounds");
		start.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, SHORTCUT_MASK));
		start.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (soundEnabled == true) {
					soundEnabled = false;
					JOptionPane.showMessageDialog(contentPane, "Sounds disabled!");
				} else {
					soundEnabled = true;
					JOptionPane.showMessageDialog(contentPane, "Sounds enabled!");
				}
					
			}
		});
		fileMenu.add(start);
		
		fileMenu.addSeparator();
		
		final JMenuItem quit = new JMenuItem("Quit");
		quit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, SHORTCUT_MASK));
		quit.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				quitIfConfirmed();			}
		});
		fileMenu.add(quit);
		
		final JMenu extrasMenu = new JMenu("Extras");
		menuBar.add(extrasMenu);
		final JMenuItem credits = new JMenuItem("Credits");
		credits.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, SHORTCUT_MASK));
		credits.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				new CreditsDialog(MenuFrame.this);
			}
		});
		extrasMenu.add(credits);
		
		extrasMenu.addSeparator();
		
		final JMenuItem intro = new JMenuItem("View intro");
		intro.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_I, SHORTCUT_MASK));
		intro.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				//TODO
			}
		});
		intro.setEnabled(false);
		extrasMenu.add(intro);
		
		setJMenuBar(menuBar);
	}
	
//	This method creates a panel which contains the preview of the chosen map 
	private final Component makeNorth(){
		final JPanel northPanel = new JPanel();
		northPanel.setLayout(new GridLayout());
		
		northPanel.add(playerPanel);
		northPanel.add(makePreview());
		
		return northPanel;
	}
	
//	This method creates a panel which contains the buttons and the choice panel
	private final Component makeSouth(){
		final JPanel southPanel = new JPanel();
		southPanel.setLayout(new GridLayout(2, 1));
		southPanel.add(makeRelativeCenter());
		southPanel.add(makeRelativeSouth());
		return southPanel;
	}
	
//	This method creates a panel which contains the choice panel
	private final Component makeRelativeCenter(){
		final JPanel centerPanel = new JPanel();
		centerPanel.setLayout(new BorderLayout());
		
		centerPanel.add(makeChooseMap(), BorderLayout.CENTER);
		
		return centerPanel;
	}
	
//	This method creates a panel which contains all the buttons
	private final Component makeRelativeSouth(){
		final JPanel southPanel = new JPanel();
		southPanel.setBorder(BorderFactory.createTitledBorder("Actions"));
		southPanel.setLayout(new BorderLayout());
        
		southPanel.add(createAndClear(), BorderLayout.WEST);
		southPanel.add(makeStart(), BorderLayout.CENTER);
		southPanel.add(quitAndEditor(), BorderLayout.EAST);
		
		return southPanel;
	}
	
//	This method creates a panel which contains the buttons create and clear
	private final Component createAndClear(){
		final JPanel createAndClearPanel = new JPanel();
		createAndClearPanel.setLayout(new GridLayout(2, 1));
		
		createAndClearPanel.add(makeCreate());
		createAndClearPanel.add(makeClear());
		
		return createAndClearPanel;
	}
	
//	This method creates a panel which contains the buttons quit and editor
	private final Component quitAndEditor(){
		final JPanel quitAndEditor = new JPanel();
		quitAndEditor.setLayout(new GridLayout(2, 1));
		
		quitAndEditor.add(makeEditor());
		quitAndEditor.add(makeQuit());
		
		return quitAndEditor;
	}
	
//	This method creates a panel where are shown the created players
	private final JPanel makePlayerPanel(){
		JPanel playerPanel = new JPanel();
		playerPanel.setBorder(BorderFactory.createTitledBorder("Players"));
		playerPanel.setSize(80, 100);
		playerPanel.setLayout(new GridLayout(8, 1));
		this.playerPanel = playerPanel;
		return playerPanel;
	}
	
//	This method creates a panel which contains preview of the chosen map
	private final Component makePreview() {
		final JPanel imagePanel = new JPanel();
		imagePanel.setBorder(BorderFactory.createTitledBorder("Map Preview"));
		ImageIcon image = new ImageIcon(getClass().getResource("previews/" + map + "Small.png"));
		imageLabel = new JLabel(image);
		imagePanel.add(imageLabel);
		imageLabel.setSize(100, 50);
		add(imagePanel);
		return imagePanel;
	}
	
//	This method creates a panel which contains the map chooser
	private final Component makeChooseMap() {
		final JPanel mapPanel = new JPanel();
		mapPanel.setPreferredSize(new Dimension(10, 5));
		
		mapPanel.setBorder(BorderFactory.createTitledBorder("Map Chooser"));
	    ButtonGroup chooseGroup = new ButtonGroup();
	    JRadioButton classic = new JRadioButton("Classic");
	      chooseGroup.add(classic);
	      mapPanel.add(classic);
	    JRadioButton map1 = new JRadioButton("Developpers");
	      chooseGroup.add(map1);
	      mapPanel.add(map1);
	     
	    classic.addActionListener(new ActionListener() {
			public void actionPerformed(final ActionEvent ev) {
				map = "classic";
				imageLabel.setIcon(new ImageIcon(getClass().getResource("previews/" + map + "Small.png")));
				pack();
			}
		});
	    map1.addActionListener(new ActionListener() {
			public void actionPerformed(final ActionEvent ev) {
				map = "map1";
				imageLabel.setIcon(new ImageIcon(getClass().getResource("previews/" + map + "Small.png")));
				pack();
			}
		});
	      
	    pack();
		add(mapPanel);
		return mapPanel;
	}
	
//	This method creates the button which quit from the game
	private final Component makeQuit() {
		final JButton quit = new JButton("Quit");
		quit.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent ev) {
                quitIfConfirmed();
            }
		});
		add(quit);
		return quit;
	}
	
//	This method creates the button to access to the editor
	private Component makeEditor() {
		final JButton editor = new JButton("Editor");
		editor.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent ev) {
                new MapNameDialog(MenuFrame.this);
            }
		});
		editor.setEnabled(false);
		add(editor);
		return editor;
	}
	
//	This method creates the button clear which clears the list of created players
	private final Component makeClear() {
		final JButton clear = new JButton("Clear");
		clear.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent ev) {
               game.getPlayers().clear();
               playerPanel.removeAll();
               checkStart();
               checkCreate();
               repaint();
            }
		});
		add(clear);
		return clear;
	}
	
//	This method creates the button which opens the dialog to create a player
	private final Component makeCreate() {
		create = new JButton("Create");
		final MenuFrame thisMenuFrame = this;
		create.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent ev) {
               new PlayerCreatorDialog(game, thisMenuFrame);
            }
		});
		add(create);
		checkCreate();
		return create;
	}
	
//	This method creates the button which starts the game
	private final Component makeStart() {
		start = new JButton("Start");
		start.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent ev) {
            	start();
            }
		});
		add(start);
		checkStart();
		return start;
	}

//	This method check if there are the right number of player to start the game and to enable the button start
	private final void checkStart() {
		if (!(game.getPlayers().size() > 1 && game.getPlayers().size() < 9)) {
			start.setEnabled(false);
		} else {
			start.setEnabled(true);
		}
	}
	
//	This method check if there are too many players
	private final void checkCreate() {
		if (game.getPlayers().size() > 7) {
			create.setEnabled(false);
		} else {
			create.setEnabled(true);
		}
	}
	
//	This method creates an option pane which waits for a confirm
	private final void quitIfConfirmed() {
		ImageIcon icon = new ImageIcon("");
        if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(MenuFrame.this, "Do you really want to quit?", "Quit?", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, icon)) {
            dispose();
            System.exit(0);
        }
    }
	
//	This method creates a label which contains the new created player
	public final void setPlayer(final String name, final String type) {
		playerPanel.add(new JLabel("   Player " + game.getPlayers().size() + " : " + name + " - " + type));
		checkStart();
		checkCreate();
		pack(); 
	}
}
